/*********************************************************************
 * Módulo 3. Tutorial de desarrollo con NME. Gestión de Capas. 
 * Programación Multimedia y Juegos
 * Autor: David Vallejo Fernández    david.vallejo@tegnix.com
 * Autor: Carlos González Morcillo   carlos.gonzalez@tegnix.com
 *
 * You can redistribute and/or modify this file under the terms of the
 * GNU General Public License ad published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * and later version. See <http://www.gnu.org/licenses/>.
 *
 * This file is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.  
 *********************************************************************/

package;

import physic.PhSprite;
import util.FpsLabel;

import aze.display.TileLayer;
import aze.display.TileSprite;
import aze.display.SparrowTilesheet;
import nme.Assets;
import nme.display.Sprite;
import nme.events.Event;
import nme.events.MouseEvent;
import nme.Lib;

import phx.World;
import phx.col.AABB;
import phx.col.SortedList;
import phx.Shape;

class HelloPhysic extends Sprite{
  var _layer:TileLayer;             // Capa principal de dibujado
  var _world:World;                 // Mundo de simulación física
  var _fpsText:FpsLabel;            // Muestra los FPS
  var _sw:Int; var _sh:Int;         // Ancho y alto de la pantalla
  var _vPhSprite:Array<PhSprite>;   // Array de Physical Sprite

  // Constructor ==================================================
  public function new() {
    super(); haxe.Timer.delay(init, 150);
  }

  function loadResources():Void {
    var sheetData:String = Assets.getText("assets/tiles.xml");
    var tilesheet:SparrowTilesheet = new SparrowTilesheet
      (Assets.getBitmapData("assets/tiles.png"), sheetData);
    _layer = new TileLayer(tilesheet);  
    _fpsText = new FpsLabel(25, 25, 0x606060, "assets/cafeta.ttf");  
    _sw = stage.stageWidth; _sh = stage.stageHeight;
    addChild(_layer.view);   addChild(_fpsText);
  }


  function addListeners():Void {
    Lib.current.stage.addEventListener(MouseEvent.CLICK, onMouseClick);
    Lib.current.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  }

  function init():Void {
    loadResources();
    _vPhSprite = new Array<PhSprite>(); 
    createPhysicWorld();           
    addListeners();
  }

  // Physic World =================================================
  function createPhysicWorld():Void {
    var size = new AABB(-1000, -1000, 1000, 1000);  // Límites 
    var bp = new SortedList();        // Método de Broadphase
    _world = new World(size, bp);     // Creación del mundo
    createLimits(_sw, _sh);           // Crea cajas estáticas
    _world.gravity = new phx.Vector(0,0.9);   // Gravedad
  }

  function createLimits(w:Float, h:Float):Void {
    // Creamos los límites del mundo: makeBox(Ancho, Alto, X, Y)
    // La X e Y de la caja tiene origen en esquina superior izqda.
    _world.addStaticShape(Shape.makeBox(w,40,0,h)); 
    _world.addStaticShape(Shape.makeBox(w,40,0,-40)); 
    _world.addStaticShape(Shape.makeBox(40,h,-40,0));
    _world.addStaticShape(Shape.makeBox(40,h,w,0));
  }

  // Update =======================================================
  function onEnterFrame(e:Event):Void {
    _world.step(1,10);
    for (p in _vPhSprite) p.update(_sw, _sh);
    _layer.render(); _fpsText.update(); 
  }
  
  // Events =======================================================
  function onMouseClick(e:MouseEvent):Void {
	if (Std.random(100) % 2 == 0) {
		var p = new PhSprite("box", _layer, _world, e.localX, e.localY);
		_vPhSprite.push(p);
	} else {
		var p = new PhSprite("gomes", _layer, _world, e.localX, e.localY);
		_vPhSprite.push(p);
	}    
  }

  // Main =========================================================
  public function main() {
    Lib.current.addChild(new HelloPhysic());
  }
}
